package com.inexas.cu.stratus;

import java.util.*;

/**
 * JUnit like test suite run from the Bootstrap
 */
public class BuildTestBigtable {
	private final Stratus bt;
	private final static int OLD = 23;
	private final static int YOUNG = 7;
	private final static String OLD_MAN_NAME = "Andy";
	private final static String YOUNG_MAN_NAME = "Bob";
	private TestEntity oldMan, youngMan;

	// Invoked by Bootstrap for the time being...
	public BuildTestBigtable() {
		// @Before
		bt = new BigtableStratus();
		bt.deleteAll(TestEntity.class);

		// void create(BigtableEntity entity);
		oldMan = new TestEntity(OLD_MAN_NAME, OLD);
		assert oldMan.getIdent() == null;
		bt.create(oldMan);
		assert oldMan.getIdent() != null;
		
		youngMan = new TestEntity(YOUNG_MAN_NAME, YOUNG);
		bt.create(youngMan);
		assert youngMan.getIdent() != null;

		testFindByIdent();
		testFindAll();
		testFindBy();
		testFindAllBy();
		testUpdate();
		testDelete();
		testDeleteAll();	// Only do this last
	}

	private void testFindByIdent() {
		final TestEntity p1 = bt.findByIdent(TestEntity.class, oldMan.getIdent());
		assert p1.getIdent() != null;
		assert p1.getAge() == OLD;
    }

    private void testFindAll() {
		final Iterator<TestEntity> all = bt.findAll(TestEntity.class);
		assert all.hasNext();
		assert all.next().getAge() == OLD;
    }

	private void testFindBy() {
		final TestEntity te = bt.findBy(TestEntity.class, "name:" + YOUNG_MAN_NAME);
		assert te.getAge() == YOUNG;
	}
	
	@SuppressWarnings("unchecked")
	private void testFindAllBy() {
		// WHERE...
		final List<TestEntity> andies = (List<TestEntity>)bt.findAllBy( //
		        TestEntity.class, //
		        "name:" + YOUNG_MAN_NAME);
		assert andies.size() == 1;
		for(final TestEntity p : andies) {
			assert p.getName().equals(OLD_MAN_NAME);
		}
		final List<TestEntity> adults = (List<TestEntity>)bt.findAllBy(TestEntity.class, "age>18");
		assert adults.size() > 0;
		for(final TestEntity p : andies) {
			assert p.getName().equals(OLD_MAN_NAME);
		}
		// ORDER BY...
		final List<TestEntity> youngestFirst = (List<TestEntity>)bt.findAllBy(TestEntity.class, "age");
		assert youngestFirst.size() > 0;
		assert youngestFirst.get(0).getAge() == YOUNG;
		final List<TestEntity> youngestFirst1 = (List<TestEntity>)bt.findAllBy(TestEntity.class, "age+");
		assert youngestFirst1.size() > 0;
		assert youngestFirst1.get(0).getAge() == YOUNG;
		final List<TestEntity> oldestFirst = (List<TestEntity>)bt.findAllBy(TestEntity.class, "age-");
		assert oldestFirst.size() > 0;
		assert oldestFirst.get(0).getAge() == OLD;
	}

	private void testUpdate() {
		// void update(BigtableEntity entity) throws NoSuchEntityException;
		final int age = oldMan.getAge();
		assert bt.findByIdent(TestEntity.class, oldMan.getIdent()).getAge() == age;
		
		oldMan.setAge(age + 1);
		bt.update(oldMan);
		assert bt.findByIdent(TestEntity.class, oldMan.getIdent()).getAge() == age + 1;
		
		oldMan.setAge(age);
		bt.update(oldMan);
		assert bt.findByIdent(TestEntity.class, oldMan.getIdent()).getAge() == age;
    }

	private void testDelete() {
		// void delete(BigtableEntity entity) throws NoSuchEntityException;
		bt.delete(oldMan);
		assert bt.findBy(TestEntity.class, "name:" + OLD_MAN_NAME) == null;
		// Put things back the way they were...
		oldMan = new TestEntity(OLD_MAN_NAME, OLD);
		bt.create(oldMan);
    }

	private void testDeleteAll() {
		// void deleteAll(Class<? extends BigtableEntity> class1);
		bt.deleteAll(TestEntity.class);
		assert bt.findAll(TestEntity.class).hasNext() == false;
    }

}
